/*
 * ppd.c
 *
 *  Created on: 23/09/2011
 *      Author: utn_so
 */

#include "../../headers/GlobalHeader.h"
//#include "../../headers/GlobalHeaderPFS.h"
#include <features.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <regex.h>
#include <unistd.h>
#include <malloc.h>
#include <math.h>
//#include <semaphore.h>
#include <stdarg.h>
#include <assert.h>
//sockets
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/un.h>

#include <pthread.h>
#include <semaphore.h>

#include <sys/wait.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>

extern int32_t contador_msync;
extern int32_t filesize;
extern char* handlerArchivoMapeado;
extern int32_t sali;
//extern char* handlerArchivoMapeado;
/*
Funcion que abre el archivo fat32 que mapea el disco (Mapping File Into Memory) devolviendo un handler
para poder realizar operaciones de E/S con el archivo.
*/



void thread_msync (){
	typedef struct timespec {
			time_t tv_sec; /* segundos */
			long   tv_nsec; /* nanosegundos */
	} timespec_t;
	int32_t valorRetorno;
	struct timespec tim, tim2;
	// tim.tv_sec = 1;
	tim.tv_nsec = 500000000;

	while(sali == 0){
		if(contador_msync > 10){
			if((valorRetorno=msync(handlerArchivoMapeado, filesize*1024, MS_SYNC)) == -1 ){
				perror("msync erroneo");
				exit(1);
			}
			contador_msync = 0;
		}else{
			nanosleep(&tim,NULL);
			if((valorRetorno=msync(handlerArchivoMapeado, filesize*1024, MS_SYNC)) == -1 ){
				perror("msync erroneo");
				exit(1);
			}
		}
	}
	return ;
}

char* ppd_abrirArchivo(){
	char* discoMapeado;
	filesize=0;
	int32_t descriptorArchivo;

	//Obtengo file descriptor
	descriptorArchivo = open (PATH_ARCHIVO_DISCO, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

	//Obtengo el tamaño del disco
	filesize=tamanioDisco();

	//Mapeo el disco
	discoMapeado = mmap(0, filesize,  PROT_READ | PROT_WRITE, MAP_SHARED, descriptorArchivo, 0);


	return discoMapeado;
}

void ppd_leerSector(int32_t sectorARetornar,char* handlerArchivoMapeado,tSector * sectorDevuelto){

	//tSector sectorDevuelto;
	int32_t tiempoLectura=0;

	//tiempoLectura=(int32_t)getInt("TiempoLectura");
	tiempoLectura=0;

	//char* handlerArchivoMapeado;

	//handlerArchivoMapeado=ppd_abrirArchivo();

	//Asigno memoria para el puntero
	//char* sectorObtenido=(char*)malloc(512);

	//Obtengo el sector
		//Copio el valor obtenido en el struct
	memcpy(sectorDevuelto->bufferSector,getSector(handlerArchivoMapeado,sectorARetornar),512);

	sleep(tiempoLectura);


//	return sectorDevuelto;
}

int32_t ppd_escribirSector(int32_t sectorAEscribir, char* bufferSector,char* handlerArchivoMapeado){

	//char *sectorGrabado;
	int32_t valorRetorno=0;
	//int32_t filesize=0;

	int32_t tiempoEscritura=0;

	//tiempoEscritura=(int32_t)getInt("TiempoEscritura");
	tiempoEscritura=0;

	//Inicializo el puntero
	//sectorGrabado = malloc(512);

	memcpy(getSector(handlerArchivoMapeado,sectorAEscribir), bufferSector,512);

	//Sincronizo el archivo para que se guarden los cambios
	//valorRetorno=msync(handlerArchivoMapeado, filesize, MS_SYNC );
	contador_msync++;
	sleep(tiempoEscritura);

	//Libero los punteros utilizados
	//free (sectorGrabado);

	return valorRetorno;
}

//Devuelve un handler con el disco apuntando al sector adecuado
char *getSector(char* handlerDiscoMapeado, int32_t sector ){
	return handlerDiscoMapeado + sector * 512;
}

int32_t tamanioDisco(){
	int32_t tamanio=0;
	int32_t cierroDescriptor=0;
	FILE *archivoDisco;

	archivoDisco = fopen(PATH_ARCHIVO_DISCO, "r" );
	fseek (archivoDisco , 0 , SEEK_END);
	tamanio = ftell (archivoDisco);
	rewind (archivoDisco);
	cierroDescriptor=fclose(archivoDisco);

	return tamanio;
}

int32_t cantidadTotalDeSectores(){

	//return ((int)(getInt("Cylinders"))*(int)(getInt("Sectors")));
	return 0;
}

